﻿package plugins.mstandio.UniversalMap.navigation {
	
	/**
	 * NavigationPoint 
	 * @author mstandio
	 */
	
	import flash.display.Bitmap;	
	import flash.display.Sprite;		
	import flash.events.Event;
	import flash.events.MouseEvent;			
	import flash.ui.Mouse;
	
	import zephyr.BroadcastEvent;
	import flash.system.ApplicationDomain;	
	import flash.utils.Dictionary;	
	import flash.utils.getDefinitionByName;	
	
	import gs.TweenLite;
	
	import plugins.mstandio.UniversalMap.UniversalMap;
	import plugins.mstandio.UniversalMap.cameras.*;
	import plugins.mstandio.UniversalMap.navigation.NavigationPointParameters;
	import plugins.mstandio.UniversalMap.navigation.MapButton;
				
	public class NavigationPoint extends Sprite {

		private var pos_x:Number;
		private var pos_y:Number;
		private var panShift:Number;		
		public  var targetSpace:String;
		private var camType:String;				
		private var camSize:Number;				
		private var camColor:String;				
				
		private var pos_x_tmp:Number;
		private var pos_y_tmp:Number;
		private var camSize_tmp:Number;
		
		private var camIsShowing:Boolean;
		private var camIsFocused:Boolean;
		
		private var params:NavigationPointParameters;
				
		private var cam:Cam;							
		
		private var mapButton:MapButton;		
		
		// classes need to be mentioned 
			private var c1:Cam_default;
			private var c2:Cam_default_short;
			private var c3:Cam_orb;
			private var c4:Cam_border;
			private var c5:Cam_border_short;
			private var c6:Cam_camera;
			
		private var BroadcastEvent:Class;
		private var ModuleLoader:Class;               
        private var moduleLoader:Object;
		private var PanoSalado:Class;			
		private var layerByName:Dictionary;
		private var panoSalado:Object;						
			
		public function NavigationPoint(pos_x:Number, pos_y:Number, panShift:Number, targetSpace:String, camType:String, camSize:Number, camColor:String):void {												
			this.pos_x = pos_x;
			this.pos_y = pos_y;
			this.panShift = panShift;			
			this.targetSpace = targetSpace;										
			this.camType = camType;
			this.camSize = camSize;
			this.camColor = camColor;						
			
			pos_x_tmp = pos_x;
		    pos_y_tmp = pos_y;
		    camSize_tmp = camSize;
			
			this.alpha = 1/UniversalMap.mapAlpha;
			this.mapButton = new MapButton();			
			this.hideCam();							
		
			if (stage) stageReady();
			else addEventListener(Event.ADDED_TO_STAGE, stageReady, false, 0, true);      
		}
		
		private function stageReady(e:Event = null):void {            
			removeEventListener(Event.ADDED_TO_STAGE, stageReady)			
			
 		    BroadcastEvent = ApplicationDomain.currentDomain.getDefinition("zephyr.BroadcastEvent") as Class;						
			ModuleLoader = ApplicationDomain.currentDomain.getDefinition("ModuleLoader") as Class;                       			
            moduleLoader = ModuleLoader(this.root.parent);						
			PanoSalado = ApplicationDomain.currentDomain.getDefinition("PanoSalado") as Class;				
			layerByName = Dictionary( moduleLoader["layerByName"] );			
			panoSalado = PanoSalado( layerByName["PanoSalado"] );				
			
			moduleLoader.addEventListener(BroadcastEvent.CAMERA_SPIN, camSpin, false, 0, true);	
			moduleLoader.addEventListener(BroadcastEvent.CAMERA_ZOOM, camZoom, false, 0, true);												
			
			this.addEventListener(MouseEvent.ROLL_OVER, over);
			this.addEventListener(MouseEvent.ROLL_OUT, out);			
			this.addEventListener(MouseEvent.MOUSE_DOWN, clicked);					
			
			this.addChild(this.mapButton);			
			this.x = this.pos_x;
			this.y = this.pos_y;
		}				
		
		public function killCam():void {
			this.camIsShowing = false;
			this.camIsFocused = true;
			
			this.mapButton.drawButton(MapButton.BUTTON_PLAIN, this.camSize);
			
			if (this.cam != null) {
				this.hideCamConfirm();
			}			
		}
		
		/**
		 * Makes navigation point clickable
		 */
		public function hideCam():void {
			this.camIsShowing = false;
			this.camIsFocused = true;															
			
			this.mapButton.drawButton(MapButton.BUTTON_PLAIN, this.camSize);			
						
			if (this.cam != null) {
				TweenLite.to(this.cam, 2, { alpha:0});
				TweenLite.delayedCall(2, hideCamConfirm);				
			}			
		}
		
		private function hideCamConfirm():void {
			this.removeChild(this.getChildByName(("cam")));
			this.cam = null;
		}
		
		
		/**
		 * Makes navigation point show camera
		 * @param	params
		 */
		public function showCam(params:NavigationPointParameters,useTween:Boolean=true):void {						
			this.params = params;
			
			this.camIsShowing = true;
			
			this.mapButton.drawButton(MapButton.BUTTON_SHOWING, this.camSize);			
			
			if (this.cam != null){
				this.removeChild(this.getChildByName(("cam")));
				this.cam = null;
			}			
			
			var camClass:Class = getDefinitionByName("plugins.mstandio.UniversalMap.cameras."+this.camType) as Class;	
			try	{
				this.cam = new camClass(params.initPan, params.initTilt, params.initZoom, this.camSize, this.panShift, this.camColor);
			}
			catch(e:Error){
				this.cam = new Cam_default(params.initPan, params.initTilt, params.initZoom, this.camSize, this.panShift, this.camColor);
			}			
			this.cam.name = "cam";
			
			this.cam.x = this.cam.y = 0;
			this.addChild(cam);	
			if(useTween){
				this.cam.alpha = 0;			
				TweenLite.to(this.cam, 2, { alpha:1 } );
			}
		}
		
		public function restorebeforeZoom():void {
			this.x = this.pos_x = this.pos_x_tmp; 
		    this.y = this.pos_y = this.pos_y_tmp;
		    this.camSize = this.camSize_tmp;
		}
		
		public function focus(useTween:Boolean = true):void {
			(MapViewer(this.parent.parent)).forceNormalCursor(false);
			(MapViewer(this.parent.parent)).gotoXY(this.x, this.y, useTween);	
			this.camIsFocused = true;
		}
		
		
		private function camSpin(e:zephyr.BroadcastEvent):void {				
			if (this.cam != null){
				if (this.camIsShowing) {					
					cam.rotate(e.info.spin.split(",")[1], e.info.spin.split(",")[0]);				
					this.params.initPan  = e.info.spin.split(",")[1]; 
					this.params.initTilt = e.info.spin.split(",")[0]; 
				}													
				if (!this.camIsFocused && (e.info.movementState != "decelerating")) {
					this.focus();						
				}			
			}			
		}				
		
		private function camZoom(e:zephyr.BroadcastEvent):void {			
			if(this.camIsShowing){
				cam.zoom(e.info.zoom);			
				this.params.initZoom = e.info.zoom;
			}
		}					
		
		private function clicked(e:Event):void {												
			if (!this.camIsShowing) {												
				this.mapButton.drawButton(MapButton.BUTTON_CLICKED, this.camSize);
				this.camIsShowing = true; // prevents multiple clicks											
				if (UniversalMap.useLoadSpacePlus) {
					moduleLoader.dispatchEvent(new BroadcastEvent(BroadcastEvent.LOADSPACEPLUS, {space:this.targetSpace}));
				}else{
					panoSalado.execute("loadSpace:" + this.targetSpace);								
				}
			}
		}
						
		private function over(e:MouseEvent):void {				
			if(!this.camIsShowing){
				(MapViewer(this.parent.parent)).forceNormalCursor(true);
				this.mapButton.drawButton(MapButton.BUTTON_OVER, this.camSize);				
			}
		}
		
		private function out(e:MouseEvent):void {	
			if(!this.camIsShowing){
				(MapViewer(this.parent.parent)).forceNormalCursor(false);			
				this.mapButton.drawButton(MapButton.BUTTON_PLAIN, this.camSize);				
			}
		}		
				
		public function getShowing():Boolean {			
			return this.camIsShowing;
		}
		
		public function setUnFocused():void{
			this.camIsFocused = false;
		}		
		
		public function rescale(ratio:Number):void {			
			this.x = this.x * ratio;
			this.y = this.y * ratio;
			// so that cameras and points wont grow to big/small after zooming
			this.camSize =( this.camSize * ratio <= 1.6) ? ( (this.camSize * ratio >= 0.5) ? this.camSize * ratio : 0.5) :  1.6 ; 		
			
			if (this.camIsShowing) {
				this.showCam(this.params,false);								
			}else {
				this.hideCam();
			}			
			
			this.setUnFocused();			
		}		
	}	
}